<?php
declare(strict_types = 1);

namespace App\Model\Logic;


use App\Helper\RedisConst;
use App\Model\Entity\Tags;
use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Bean\Annotation\Mapping\Inject;
use Swoft\Redis\Pool;

/**
 * @Bean()
 * Class FormatDataLogic
 * @package App\Model\Logic
 */
class FormatDataLogic
{
    /**
     * @Inject("redis.pool")
     * @var Pool
     */
    private $redis;

    /**
     * @Inject("redis1.pool")
     * @var Pool
     */
    private $redis1;

    /**
     * @Inject()
     * @var MemberRedisLogic
     */
    private $member_redis;


    /**
     * @Inject()
     * @var RelationShipLogic
     */
    private $relationship_logic;


    /**
     * @Inject()
     * @var CollectLogic
     */
    private $collect_logic;

    /**
     * @Inject()
     * @var PraiseLogic
     */
    private $praise_logic;


    /**
     * @Inject()
     * @var PostCacheLogic
     */
    private $postcache_logic;

    /**
     * @Inject()
     * @var PostEsLogic
     */
    private $post_es_logic;

    /**
     * @Inject()
     * @var AesLogic
     */
    private $aes_logic;

    /**
     * @Inject()
     * @var ShopLogic
     */
    private $shop_logic;



    private $members_data = [];
    private $ships = [];
    private $praise_state = [];
    private $post_cache = [];
    private $collection = [];


    /**
     * --------------------------------------------------------------------------
     * 渲染帖子列表
     * --------------------------------------------------------------------------
     * @param array $post_list
     * @param int $login
     * @param string $version
     * @param string $device
     * @return array
     */
    public function renderPostList($post_list, $login, $version, $device, $lang = 'en', $is_recommend = false)
    {
        if(!$post_list) return [];
        $member_ids = array_column($post_list, 'member_id');
        $this->members_data = $this->getMemberDataByIds($member_ids);
        $this->members_data = array_column($this->members_data, null, 'member_id');
        $this->ships = $this->relationship_logic->multiMembership($login, $member_ids);
        $post_ids = array_column($post_list, 'id');
//        $this->praise_state = $this->praise_logic->multiPraised($login, $post_ids);
//        $this->post_cache = $this->postcache_logic->multiPostExtendCache($post_ids);
        $this->collection = $this->collect_logic->multiCollection($login, $post_ids);

        //批量获取post数据
        $post_caches = $this->multiPostData($post_ids);
        foreach($post_list as $k => $post_data){
            $post = $post_caches[$k];
            if(1) //!$post)
            {
                switch ($post_data['category'])
                {
                    case 'news':
                    case 'hotnews':
                        $post = $this->renderNews($post_data);
                        break;
                    default:
                        $post = $this->renderSinglePost($post_data, $login, $version, $lang, $k, $is_recommend);
                        break;
                }
                $this->redis->set(RedisConst::TMP_RENDER_POST . $post_data['id'], var_export($post , true), 3600);
            }else{
                eval('$post=' . $post . ';');
                $post = $this->renderPostCache($post, $login, $k, $lang);
            }

            $data[] = $post;
        }
        return $data;
    }



    /**
     *
     * 批量获取用户数据
     * @param $member_ids
     * @param bool $business_account
     * @return array
     * @throws \ReflectionException
     * @throws \Swoft\Bean\Exception\ContainerException
     */
    public function getMemberDataByIds($member_ids,  $business_account = true)
    {
        $func = function($pipe) use($member_ids) {
            foreach($member_ids as $member_id)
            {
                $pipe->hgetall(RedisConst::MEMBER . $member_id);
            }
        };
        $members = $this->redis1->pipeline($func);
        if(!$members) return [];
        $i = 0;
        $data = [];
        foreach($members as $member){
            if(!$member || !isset($member['uuid'])) {
                $member = $this->member_redis->info($member_ids[$i]);
                if(!$member) continue;
            }
            if($member['status'] != 1) continue;
            if(!$business_account && $member['type'] != 1) continue;
            $data[] = [
                'member_id' => (int) $member['id'],
                "member_uuid" => $member['uuid'],
                'role' => config('app.business_conf.'.$member['type']),// shop 、 brand
                'business_id' => (int) $member['type_id'],
                'member_name' => [
                    'nickname'  => $member['type'] == 1 ? $member['nickname'] : $member['displayname'],
                    'displayname' => $member['displayname'],
                    'icon'    => $this->getMemberIcon($member['id']),
                ],
                'avatar' => formatAvatar($member['avatar']),
            ];
        }
        return $data;
    }


    /**
     * 人物icon显示数据格式化
     * @param $member_id
     * @return array
     * @throws \ReflectionException
     * @throws \Swoft\Bean\Exception\ContainerException
     */
    public function buildMemberIcon($member_id)
    {
        $info = $this->member_redis->info($member_id);
        if(!$info) return [];
        $data = [
            'member_uuid' =>  $info['uuid'],
            "member_id" => (int) $info['id'],
            'uuid' => $info['uuid'],
            'role' => config('app.business_conf.'.$info['type']),// shop 、 brand
            'business_id' => (int) $info['type_id'],
            'member_name' => [
                'nickname'  => $info['type'] == 1 ? $info['nickname'] : $info['displayname'],
                'displayname' => $info['displayname'],
                'icon'    => $this->getMemberIcon($info['id']),
            ],
            'avatar' => formatAvatar($info['avatar']),
        ];
        return $data;
    }




    /**
     * --------------------------------------------------------------------------
     * 获取member icon
     * --------------------------------------------------------------------------
     * @param $member_id
     * @return array
     */
    public function getMemberIcon($member_id)
    {
        $k = RedisConst::RENDERTAGMEMBERICON . $member_id;
        $icon = $this->redis->get($k);
        if(!$icon){
            $key = RedisConst::TAGMEMBERICON . $member_id;
            $icons = $this->redis->get($key);
            if(!$icons) return [];
            $icon = [];
            $icons = json_decode($icons, true);
            foreach($icons as $icon_id)
            {
                $icon[] = $this->getTagById($icon_id);
            }
            $this->redis->set($k, JSON($icon), 600);
            return $icon;
        } else {
            $icon = json_decode($icon, true);
            return $icon;
        }
    }

    /**
     * --------------------------------------------------------------------------
     * 根据tag id获取对应的图标或者文本
     * --------------------------------------------------------------------------
     * @param $tag_id
     * @return string
     */
    public function getTagById($tag_id)
    {
        $key = RedisConst::TAGICON . $tag_id;
        $icon = $this->redis->get($key);
        if($icon) return config('app.amazonCDN.img') . $icon;
        $icon = $this->setTagCache($tag_id);
        return config('app.amazonCDN.img') . $icon;
    }


    /**
     * 重构tag缓存数据
     * @param $tag_id
     * @return |null
     * @throws \ReflectionException
     * @throws \Swoft\Bean\Exception\ContainerException
     * @throws \Swoft\Db\Exception\DbException
     */
    public function setTagCache($tag_id)
    {
        $key = RedisConst::TAGICON . $tag_id;
        $data = Tags::where('id', $tag_id)->first()->toArray();
        if(!$data) return null;
        $this->redis->set($key, $data['icon']);
        return $data['icon'];
    }




    /**
     * --------------------------------------------------------------------------
     * 渲染单个帖子
     * --------------------------------------------------------------------------
     * @param array $post_data
     * @param int $login
     * @param string $version
     * @param string $lang
     * @param string $device
     * @return array
     */
    public function renderSinglePost($post_data, $login, $version, $lang = 'en', $k=null)
    {
        //用户数据
        $member = isset($this->members_data[$post_data['member_id']]) ? $this->members_data[$post_data['member_id']] : [];
        if(!$member) {
            $member = $this->buildMemberIcon($post_data['member_id']);
        }
        //转发贴数据
        $origin_info = [];
        if(!empty($post_data['original'])){
            $origin = $this->post_es_logic->getPostById($post_data['original']);
            if($origin){
                if($login == $origin['member_id'] && $origin['status'] ==4)  $origin['status'] =1;
                $origin_info=  $this->formatOrigin($origin, $login, $lang, $version);
                $origin_info = toArray($origin_info);
            }
        }

        // post数据
        $is_praise = isset($this->praise_state[$k]) && is_numeric($this->praise_state[$k]) ? 1 : 0;
        $is_follow = $login && isset($this->ships[$post_data['member_id']]) ? $this->ships[$post_data['member_id']] : 0;
//        $post_cache = $this->post_cache[$k] ? $this->post_cache[$k] : $this->postcache_logic->setExtInfo($post_data['id']);
        $thumb_size = config('app.thumb_size');
        $nickname = isset($member['member_name']['nickname']) ?  $member['member_name']['nickname'] : '';

        $data = [
            'post_id'      => (int)$post_data['id'],
            'title'        => isset($post_data['title']) ? decode_ascii_string($post_data['title']) : "",
            'content'      =>  $post_data['original'] ? $post_data['repeat_content'] : $post_data['content'],
            'images'       =>  formatPicture($post_data['images']),
            'video'        =>  isset($post_data['trans']) ? formatVideo($post_data['video'], $post_data['trans']) : null ,
            'video_cover'  =>  formatVideoCover($post_data['video_cover']),
            'video_cover_ratio' => !empty($post_data['video_cover_ratio']) ? $post_data['video_cover_ratio'] : 1,
//            'praise_num'   => isset($post_cache['praise']) ? intval($post_cache['praise']) : 0,
//            'comments_num' => isset($post_cache['comment']) ? intval($post_cache['comment']) : 0,

//            'comments_num' => (new Comment())->getCommentDeepCountByPostId($post_data['id']), //intval($post_extend['comment']),
//            'praise_num' => (new PostCache())->getPostPraiseTotal($post_data['id']), //intval($post_extend['praise']),

            'original'     => $post_data['original'],
            'publish_addr' => $post_data['publish_addr'],
            'created_at'     => intval($post_data['created_at']),
            'origin_content' => $post_data['original'] ? trim($post_data['content']) : '',
            'thumb_size'   => $thumb_size,
            'type'         => $post_data['type'],
            'share_url'    => $post_data['original'] ? env('SHARE_URL').'wap/postdetail/'.$post_data['original'] : env('SHARE_URL').'wap/postdetail/'.$post_data['id'],
            'is_praise'    => $is_praise,
            'is_follow'    => $is_follow,//$this->follow_redis->membership($login, $post_data['member_id']),
            'attention'    => isset($post_data['attention']) ? $this->formatAttention($post_data['attention']) : [] ,
            'category'     => $post_data['category'],
            'is_collect'   => 1, // $this->collection[$k] ? 1 : 0,
            'brand_topic_id' => isset($post_data['brand_topic_id']) ? intval($post_data['brand_topic_id']) : 0,
            'brand_topic'  => isset($post_data['brand_topic_id']) && $post_data['brand_topic_id'] ? $this->brand_topic->getBrandTopicFromRedis($post_data['brand_topic_id']) : '',
            'is_choice'    => isset($post_data['is_choiceness']) ? intval($post_data['is_choiceness']) : 0,
            'is_deals'     => isset($post_data['is_deals']) ? intval($post_data['is_deals']) : 0,
            'from'         => isset($post_data['category']) && isset($post_data['platform']) && $post_data['platform'] && ($post_data['category'] == 'news') ? config('app.news_platform')[$post_data['platform']] : $nickname,
            'offset'       => isset($post_data['offset']) ? floatval($post_data['offset']) : 0,
            'recommend_state'       => !empty($post_data['recommend_state']) ? 1 : 0,
            'ticket'        => $this->aes_logic->aesPostToken((int)$post_data['id'], $login)

        ];

        //3.6.7 以及版本  youtube类型铁则逻辑上修改为  posts  和  type=3 的类型。。
        if($post_data['category'] == 'youtube') // && $version >= '3.6.7' )
        {
            $data['type'] = 3;
            $data['category'] = 'posts';
        }

        $data['shop_id'] = isset($post_data['shop_id'])  ? intval($post_data['shop_id']) : 0;
        if(!empty($post_data['shop_id']))
        {
            $post_score = isset($post_data['shop_score']) && intval($post_data['shop_score']) > 0 ? $post_data['shop_score'] : 0;
            if($post_data['shop_id'] && !$data['is_deals'] && !$post_score) {
                $data['shop_score'] = '10.0';
            }
            if(!$post_score) $post_data['shop_id'] = 0;
            if($post_score) $data['shop_score'] = shopScoreFormat($post_score);
        }
        $data['shop_name'] = '';
        if(isset($data['is_deals']) && $data['is_deals']){
            $data['shop_id'] = 0;
        }
        if($data['shop_id']){
            $shop = $this->shop_logic->getShopInfoById($data['shop_id']);
            if($shop) $data['shop_name'] = $shop['name'];
        }
        if(isset($post_data['challenge']) && $post_data['challenge']) {
            $data['challenge'] = json_decode($post_data['challenge'], true);
        }

        return array_merge($member, $origin_info, $data);
    }


    /**
     * 格式化源动态数据
     * @param $post_data
     * @param string $lang
     * @param $version
     * @param $login
     * @return array|\stdClass
     */
    public function formatOrigin($post_data, $login, $lang = 'en')
    {
        if(!$post_data) return (new \stdClass());
        $member = $this->buildMemberIcon($post_data['member_id']);
        $tips = [
            0 => config('lang_'.$lang.'.disabled_conf.text'),
            1 => '',
            2 => config('lang_'.$lang.'.delete_post'),
            3 => config('lang_'.$lang.'.disabled_conf.text'),
            4 => config('lang_'.$lang.'.disabled_conf.text'),
        ];

        $original = [
            'origin_member_id' => $member['member_id'],
            'origin_member_uuid' => $member['member_uuid'],
            'origin_member_name'  =>  $member['member_name'],
            'origin_avatar' => $member['avatar'],
            'origin_is_follow' => $this->relationship_logic->membership($login, $post_data['member_id']),

        ];
        $original['origin_business_id'] = $member['business_id'];
        $original['origin_role'] = $member['role'];
        $is_praise = $this->praise_logic->isPraised($login, $post_data['id']) ? 1 : 0;
        $original['origin_status'] = $post_data['status'];
        $original['origin_content'] = $post_data['content'];
        $original['origin_tips'] = $tips[$post_data['status']];
        $original['origin_created_at'] = $post_data['created_at'];
        $original['origin_category']   = isset($post_data['category'])? $post_data['category']: 'posts';
        $original['origin_news_url'] = ($original['origin_category'] == 'news') ? config('app.news_share_url'). $post_data['id'] : '';
        $original['origin_praise_num'] = $post_data['praise_num'];
        $original['origin_comments_num'] = $post_data['comments_num'];
        $original['origin_is_praise']  = $is_praise;
        $original['origin_is_collect'] = $this->collect_logic->isMembers($login, $post_data['id']) ? 1 : 0;
        $original['origin_ticket'] =  $this->aes_logic->aesPostToken($post_data['id'], $login);
        $original['origin_category']   = 'posts';

        return $original;
    }


    //批量获取post数据
    public function multiPostData($post_ids)
    {
        $func = function($pipe) use($post_ids){
            foreach($post_ids as $post_id){
                $pipe->get(RedisConst::TMP_RENDER_POST .$post_id);
            }
        };
        return $this->redis->pipeline($func);

    }

    /**
     * --------------------------------------------------------------------------
     * 格式化一个news post
     * --------------------------------------------------------------------------
     * @param $news
     * @return array
     */
    public function renderNews($news, $k=0)
    {
        $member_data = [];
        if($news['member_id'])
        {
            $member_data = $this->member_redis->info($news['member_id']);
            if($member_data['type'] != 1) $member_data['nickname'] = $member_data['displayname'];
        }
        $thumb_size = config('app.thumb_size');

        $tmp_nickname = isset($member_data['nickname']) ? $member_data['nickname'] : "";
        $title = isset($news['title']) ? $news['title'] : '';
        $post_cache = isset($this->post_cache[$k]['read_num']) ? $this->post_cache[$k] : $this->post_cache_handle->setExtInfo($news['id']);
        return [
            'category' => $news['category'],
            'post_id'  => $news['id'],
            'title' => buildNewsTitle($news['category'], $title, $news['content']),
            'from'  => isset($news['category']) && isset($news['platform']) && $news['platform'] && ($news['category'] == 'news') ? config('app.news_platform')[$news['platform']] : $tmp_nickname,
            'read_num' => intval($post_cache['read_num']),
            'created_at' => intval($news['created_at']),
            'images'       => formatPicture($news['images']),
            'video'        => formatVideo($news['video'], $news['trans']),
            'video_cover'  => formatVideoCover($news['video_cover']),
            'video_cover_ratio' => $news['video_cover_ratio'] ? $news['video_cover_ratio'] : 1,
            'thumb_size' => $thumb_size,
            'ticket' => $this->aes_logic->aesPostToken($news['id'])
        ];
    }


    /**
     * --------------------------------------------------------------------------
     * 格式化@
     * --------------------------------------------------------------------------
     * @param $attention //json数据
     * @return array
     */
    public function formatAttention($attention)
    {
        if(!$attention) return [];
        $temp = [];
        $attention = json_decode($attention, true);
        foreach($attention['nickname'] as $key => $val){
            $member_id = (int)$attention['member_ids'][md5(strtolower($val))];
            $member_info = $this->buildMemberIcon($member_id);
            $temp[] = [
                'member_id' => $member_id,
                'member_uuid' => $member_info['member_uuid'],
                'role' => 'normal',
                'business_id' => 0,
                'member_name'  => [
                    'nickname' => $val,
                ],

            ];
        }
        return $temp;
    }

}